package com.godofgamblers.hotelmanagementsystem.handler;

import com.godofgamblers.hotelmanagementsystem.dto.OrderItemDTO;
import com.godofgamblers.hotelmanagementsystem.dto.TimeAndRoomTypeId;
import com.godofgamblers.hotelmanagementsystem.dto.TimeDto;
import com.godofgamblers.hotelmanagementsystem.pojo.Cart;
import com.godofgamblers.hotelmanagementsystem.pojo.Order;
import com.godofgamblers.hotelmanagementsystem.pojo.Order_item;
import com.godofgamblers.hotelmanagementsystem.pojo.User;
import com.godofgamblers.hotelmanagementsystem.service.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author wzx
 * @date 2019/10/14 - 13:58
 * 订单类handler
 * 点击创建订单执行该类
 */
@Controller
@RequestMapping("/order")
@Scope("prototype")
public class OrderHandler {
    @Resource
    private OrderService orderService;
    @Resource
    private CartService cartService;
    @Resource
    private Order_ItemService order_itemService;
    @Resource
    private Room_TypeService room_typeService;
    @Resource
    private Check_In_InfoService check_in_infoService;



    @RequestMapping("/creat")
    @ResponseBody
    //用户点击创建订单，前台发送数据total_price，pay_way，leave_message_context-------选中的订单项
    //#{order_num},#{user_id},#{total_price},#{order_time},#{pay_way},#{leave_message_context}
    public String insertOrder(Order order, String[] check) {
         Map<Integer, TimeAndRoomTypeId> mapall = new HashMap<>();
        System.out.println("进入insertOrder_handler");
        System.out.println(order);
        Session session = SecurityUtils.getSubject().getSession();    //取出session
        Object obj = session.getAttribute("user");   //获得user
        User user = (User) obj;  //获取到当前用户
        //向订单表中插入数据
        Date date = new Date();
        Long order_nums = date.getTime();//通过时间戳保证生成不重复的订单号
        String order_num = order_nums.toString();   //生成的订单号
        String order_time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);   //获取创建订单时候的时间
        order.setOrder_num(order_num);//设置订单号
        order.setOrder_time(order_time);//设置订单创建时间
        order.setUser_id(user.getUser_id());//设置user_id
        //check[]数组表示前台在购物车中选择的序列id数组  装有cart_id


        for (String c : check) {
            TimeAndRoomTypeId timeAndRoomTypeId = new TimeAndRoomTypeId();
            Integer cart_id = Integer.parseInt(c);
            Map<String, Integer> map = new HashMap<>();
            map.put("cart_id", cart_id);
            map.put("user_id", user.getUser_id());
            Cart cart1 = cartService.findRoomTypeID(map);//查到每笔订单项的所属的购物车对象
            //取得计划入住时间
            String stay_time = cart1.getPlan_stay_time();
            //取得计划离店时间
            String leave_time = cart1.getPlan_leave_time();
            //取得该项的room_type_id
            Integer room_type_id = cart1.getRoom_type_id();
            timeAndRoomTypeId.setPlan_stay_time(stay_time);
            timeAndRoomTypeId.setPlan_leave_time(leave_time);
            timeAndRoomTypeId.setRoom_type_id(room_type_id);
            mapall.put(cart_id,timeAndRoomTypeId);
        }

        //遍历mapall
        for (TimeAndRoomTypeId v : mapall.values()) {
            Integer room_type_id = v.getRoom_type_id();
            //传入对象去查询该时间段该房间类型被预定了多少
            List<Order_item> list = orderService.findnewStock(v);
            Integer num = list.size();  //当前时间段已经被预定的数量  5
            //查询库存数量                                           6
            Integer stocks = orderService.findStock(room_type_id);
            if (1 + num > stocks) {
                mapall.clear();
                return v.getRoom_type_id() + "该时间段内已经没有足够房间，请重新选择";
            }
        }
        //确保每一项都有库存 在做操作
        //通过订单号找到此订单的order_id
        orderService.insertOrder(order);    //向订单表中插入数据
        Integer order_id = orderService.findOrderByOrderNum(order_num);
        for (String c : check) {
            Integer cart_id = Integer.parseInt(c);
            Map<String, Integer> map = new HashMap<>();
            map.put("cart_id", cart_id);
            map.put("user_id", user.getUser_id());
            Cart cart1 = cartService.findRoomTypeID(map);//查到每笔订单项的所属的购物车对象
            //通过order_id向订单项表中插入数据order_id,room_type_id,plan_stay_time,plan_leave_time
            Order_item order_item = new Order_item();
            order_item.setOrder_id(order_id);//设置order_id
            order_item.setRoom_type_id(cart1.getRoom_type_id());
            order_item.setPlan_stay_time(cart1.getPlan_stay_time());
            order_item.setPlan_leave_time(cart1.getPlan_leave_time());
            if (order.getPay_way() == 1) {
                //线下支付，将订单项状态设为3
                order_item.setOrder_item_state(3);
            } else if (order.getPay_way() == 0) {
                //线上支付
                order_item.setOrder_item_state(0);
                //使用定时器
                timeCutDown(order_num);
            } else if (order.getPay_way() == 2) {
                //钱包余额支付
                order_item.setOrder_item_state(0);
            }
            order_itemService.insertOrderItem(order_item);
        }
        mapall.clear();
        System.out.println("*************************************"+order_num);
        return order_num;

    }


    @RequestMapping("/countdown")
    @ResponseBody
    //确认订单界面倒计时15分钟后执行的handler，前台传来订单号，查询对应的订单状态看如果是0（未支付）将对应的订单状态变为3（已失效）
    public String updateOrderState(String order_num, String[] check, Integer pay_way) {
        System.out.println("++++++++++++++++++++++++++++++++++++进入倒计时，" + order_num);
        System.out.println("支付方式" + pay_way);
        if (pay_way == 0) {//线上支付
            //查询对应的状态
            Integer state = orderService.findOrderState(order_num);
            if (state == 0) {
                //如果仍然是未支付状态，就变成已失效---3
                orderService.updateOrderState(order_num);
                //清空该用户的购物车，找到选中的一些id,
                for (String c : check) {
                    Integer cart_id = Integer.parseInt(c);
                    cartService.deleteSomeCart(cart_id);
                }
                return "过期了";
            }
            return "线上已经付款";
        }
        return "线下付款或者钱包余额支付";

    }

    @RequestMapping("/cartdelete")
    @ResponseBody
    //移除购物车中的某项
    public String deleteGood(String[] check) {
        System.out.println(check);
        for (String c : check) {
            Integer cart_id = Integer.parseInt(c);
            cartService.deleteSomeCart(cart_id);
        }
        return "删除成功";
    }

    //在模态框中点击取消，改变订单状态（将订单号传过来）
    @RequestMapping("/changeOrderState")
    @ResponseBody
    public String changeOrderState(String order_num) {
        orderService.changeOrderState(order_num);   //改变订单状态  改变为已取消 2
        //改变订单项状态，改变为用户取消 4
        Integer order_id = orderService.findOrderByOrderNum(order_num); //通过订单号码找到订单id
        order_itemService.updateOrderItemStates(order_id);  //将订单项中所有属于该订单的项目状态改为4
        return "取消成功";
    }

    //不选择加入购物车，直接点击预定方式
    @RequestMapping("/orderroom")
    @ResponseBody
    public String orderRoom(Integer room_type_id, String plan_stay_time, String plan_leave_time, Integer pay_way, String context, BigDecimal total_price) {
        System.out.println("单独预定咯******************************");

        String stay_time = plan_stay_time;
        String leave_time = plan_leave_time;
        String[] ss  = stay_time.split("/");
        String[] sa  = leave_time.split("/");
        String plan_stay_time1 = ss[2]+"-"+ss[0]+"-"+ss[1];
        String plan_leave_time1 = sa[2]+"-"+sa[0]+"-"+sa[1];

        //封装对象
        TimeAndRoomTypeId timeAndRoomTypeId = new TimeAndRoomTypeId();
        timeAndRoomTypeId.setRoom_type_id(room_type_id);
        timeAndRoomTypeId.setPlan_stay_time(plan_stay_time1);
        timeAndRoomTypeId.setPlan_leave_time(plan_leave_time1);
        //判断当前的库存
        List list = orderService.findnewStock(timeAndRoomTypeId);  //在这个时间段的所有订单
        Integer num = list.size();  //判断定了多少该房间出去了
        //查看该类型房间的库存
        Integer stock = orderService.findStock(room_type_id);
        if (stock - num < 1) {
            //代表该时间段没有库存了
            return "该时段该房间类型已经预定满了噢";
        }
        //有库存，进行插入
        //插入订单表
        Order order = new Order();
        //生成时间蹉为订单号
        Date date = new Date();
        Long ordernum = date.getTime();
        String order_num = ordernum.toString();//订单号码
        //Integer user_id = 1;                //用户id
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("user");
        String order_time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);   //获取创建订单时候的时间

        order.setUser_id(user.getUser_id());
        order.setOrder_time(order_time);
        order.setOrder_num(order_num);
        order.setPay_way(pay_way);
        order.setTotal_price(total_price);
        order.setLeave_message_context(context);
        //向订单表中插入数据
        orderService.insertOrder(order);
        //找到该订单的order_id
        Integer order_id = orderService.findOrderByOrderNum(order_num);
        //向订单项中插入数据
        Order_item orderItem = new Order_item();//构建对象
        orderItem.setOrder_id(order_id);//订单id
        orderItem.setRoom_type_id(room_type_id);//房间类型id
        orderItem.setPlan_stay_time(plan_stay_time1);//入住时间
        orderItem.setPlan_leave_time(plan_leave_time1);//离开时间

        if (pay_way == 1) {
            orderItem.setOrder_item_state(3);
        } else if (pay_way == 0) {
            //线上支付，使用15分钟定时器
            orderItem.setOrder_item_state(0);
            //使用定时器
            timeCutDown(order_num);

        } else if (pay_way == 2) {
            orderItem.setOrder_item_state(0);
        }
        //插入订单项
        order_itemService.insertOrderItem(orderItem);
        return order_num;
    }

    //用户选择钱包余额支付，查询到用户的余额
    @ResponseBody
    @RequestMapping("/paywallet")
    public String payByWallet(BigDecimal total_price, String user_password, String order_num) {
        //判断支付密码是否正确，通过用户去找到密码
        System.out.println(total_price + "###" + user_password + "####" + order_num);
        Session session = SecurityUtils.getSubject().getSession();
       User user = (User)session.getAttribute("user");

       String pwd = new SimpleHash("MD5",user_password,"1024").toString();
        if (!pwd.equals(user.getUser_password())) {
            //将对应的订单flag改为0，删除
            orderService.updateOrderFlag(order_num);
            return "密码输入错误,请重新预定并输入正确密码";
        }
        //查询到用户的余额:findUserWallet方法
        //BigDecimal user_wallet = new BigDecimal(600000);
        BigDecimal user_wallet = orderService.findUserWallet(user);
        if (user_wallet.compareTo(total_price) == 1) {
            //用户钱包余额比支付金额高---->可支付
            BigDecimal balance = user_wallet.subtract(total_price); //支付成功的余额
            //修改用户的余额,updateUserWallet方法
            user.setUser_wallet(balance);   //设置钱包余额
            orderService.updateUserWallet(user);
            System.out.println(balance + "*************************************************");
            //将订单状态改为已支付
            orderService.updateStateWallet(order_num);
            //订单项状态改为未使用
            Integer order_id = orderService.findOrderByOrderNum(order_num);
            System.out.println("order_id"+order_id);
            order_itemService.updateOrderItemState(order_id);
            return "支付成功";
        }
        return "钱包余额不足，请充值后在付款";

    }

    //ch查询自己的待评价信息
    @RequestMapping("/common")
    @ResponseBody
    public List<OrderItemDTO> findCommonInfo(){
       Object obj =  SecurityUtils.getSubject().getSession().getAttribute("user");
       if(obj==null){
           return null;
       }
       User user = (User)obj;
       List<OrderItemDTO> list = order_itemService.findDto(user.getUser_id());
       //遍历集合，将集合中的room_type_name找到，实际入住和退房时间找到
        for (OrderItemDTO itemDTO : list){
            Integer room_type_id = itemDTO.getRoom_type_id();
            String name = room_typeService.findRoomTypeName(room_type_id);
            itemDTO.setRoom_type_name(name);
            Integer order_item_id = itemDTO.getOrder_item_id();
            TimeDto dto = check_in_infoService.findTime(order_item_id);
            itemDTO.setCheck_in_time(dto.getCheck_in_time());
            itemDTO.setCheck_out_time(dto.getCheck_out_time());
        }

        return list;
    }

  //倒计时工具类
    public void timeCutDown(String order_num) {
        //设定定时器
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //去查询当前订单编号的订单状态，如果仍然是0（未支付），则修改为3（已失效）
                //查询对应的状态
                Integer state = orderService.findOrderState(order_num);
                if (state == 0) {
                    //如果仍然是未支付状态，就变成已失效---3
                    orderService.updateOrderState(order_num);
                }
            }

        }, 600000);
    }
}
